package com.ABdolphin.forum.services.impl;

import com.ABdolphin.forum.common.AppResult;
import com.ABdolphin.forum.common.ResultCode;
import com.ABdolphin.forum.dao.UserMapper;
import com.ABdolphin.forum.exception.ApplicationException;
import com.ABdolphin.forum.model.User;
import com.ABdolphin.forum.services.IUserService;
import com.ABdolphin.forum.utils.MD5Util;
import com.ABdolphin.forum.utils.StringUtil;
import com.ABdolphin.forum.utils.UUIDUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.Date;

@Service
@Slf4j
public class UserServiceImpl implements IUserService {
    @Resource
    private UserMapper userMapper;

    @Override
    public void createNormalUser(User user) {
        User selectedUser = userMapper.selectByUserName(user.getUserName());
        if (selectedUser!=null){
            //用户已存在
            log.info("用户已经存在,普通用户创建失败. userName={}",user.getUserName());
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_EXISTS));
        }
        //对用户的其他信息进行默认值设置
        user.setGender((byte)2);
        user.setArticleCount(0);
        user.setIsAdmin((byte)0);
        user.setState((byte)0);
        user.setDeleteState((byte)0);
        user.setCreateTime(new Date());
        user.setUpdateTime(new Date());
        int result = userMapper.insertSelective(user);
        if(result<1){
            log.error("数据库插入普通新用户失败");
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_CREATE));
        }
    }

    @Override
    public User login(String userName, String password) {
        User selectedUser = userMapper.selectByUserName(userName);
        if (selectedUser==null){
            //用户已存在
            log.info("用户不存在,登录失败. userName={}",userName);
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        String unverifiedMD5Password = MD5Util.md5(password, selectedUser.getSalt());
        if (!selectedUser.getPassword().equals(unverifiedMD5Password)){
            log.info("用户名或密码输入不正确,userName={}"+userName);
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_LOGIN));
        }
        log.info("登陆成功:userName={}"+userName);
        return selectedUser;
    }

    @Override
    public User selectById(Long id) {
        if (id==null){
            log.info("id为空");
            throw new ApplicationException(AppResult.fail());
        }
        User user = userMapper.selectByPrimaryKey(id);
        return user;
    }

    @Override
    public void modifyInfo(User user) {
        //校验参数
        if (user==null||user.getId()==null||user.getId()<=0){
            log.info(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        //用户是否存在
        User selectUser = userMapper.selectByPrimaryKey(user.getId());
        if (selectUser==null||selectUser.getDeleteState()==1){
            log.info(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        //创建一个新的user对象
        User updateUser = new User();
        updateUser.setId(user.getId());
        boolean check=false;
        //校验用户名是否合法
        if (!StringUtil.isEmpty(user.getUserName())
                &&!user.getUserName().equals(selectUser.getUserName())){
            User byUserName = userMapper.selectByUserName(user.getUserName());
            if (byUserName!=null){
                log.info("用户名已存在,更改失败");
                throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_EXISTS,"该用户名已占用"));
            }
            updateUser.setUserName(user.getUserName());
            check=true;
        }
        //校验昵称
        if(!StringUtil.isEmpty(user.getNickname())
                &&!user.getNickname().equals(selectUser.getNickname())){
            updateUser.setNickname(user.getNickname());
            check=true;
        }
        //校验性别
        if(user.getGender()!=null
                &&user.getGender()>=0
                &&user.getGender()<=2
                &&!user.getGender().equals(selectUser.getGender())){
            updateUser.setGender(user.getGender());
            check=true;
        }
        //邮箱校验
        if (!StringUtil.isEmpty(user.getEmail())
                &&!user.getEmail().equals(selectUser.getEmail())){
            updateUser.setEmail(user.getEmail());
            check=true;
        }
        //电话号码校验
        if (!StringUtil.isEmpty(user.getPhoneNum())
                &&!user.getPhoneNum().equals(selectUser.getPhoneNum())
                &&user.getPhoneNum().length()==11){
            updateUser.setPhoneNum(user.getPhoneNum());
            check=true;
        }
        //校验个人简介
        if (!StringUtil.isEmpty(user.getRemark())
                &&!user.getRemark().equals(selectUser.getRemark())){
            updateUser.setRemark(user.getRemark());
            check=true;
        }
        if (check==false){
            log.info(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        updateUser.setUpdateTime(new Date());
        int result = userMapper.updateByPrimaryKeySelective(updateUser);
        if (result<=0){
            log.warn(ResultCode.FAILED.toString()+", 受影响行数不等于1,");
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED));
        }
        log.info(ResultCode.SUCCESS.toString());
    }

    @Override
    public void modifyPassword(Long id, String oldPassword, String newPassword) {
        User user = userMapper.selectByPrimaryKey(id);
        //检验用户是否存在
        if (user==null){
            log.info(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        //检验旧密码是否正确
        if (!MD5Util.md5(oldPassword,user.getSalt()).equals(user.getPassword())){
            log.info("密码错误");
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_LOGIN ,"初始密码错误"));
        }
        //检验新旧密码是否相同
        if (MD5Util.md5(newPassword,user.getSalt()).equals(user.getPassword())){
            log.info(ResultCode.FAILED_NEW_OLD_PWD_SAME.toString());
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_NEW_OLD_PWD_SAME));
        }
        //重新生成盐
        String salt = UUIDUtil.UUID_32();
        String newPasswordMd5 = MD5Util.md5(newPassword, salt);
        User updateUser = new User();
        updateUser.setId(user.getId());
        updateUser.setPassword(newPasswordMd5);
        updateUser.setSalt(salt);
        updateUser.setUpdateTime(new Date());
        int result = userMapper.updateByPrimaryKeySelective(updateUser);
        if (result<=0){
            log.warn(ResultCode.FAILED.toString()+", 受影响行数不等于1,");
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED));
        }
        log.info(ResultCode.SUCCESS.toString());
    }

    @Value("${app.upload.avatar-dir}")
    private String avatarDir;

    @Override
    public String modifyImage(Long id, MultipartFile file) throws IOException {
        User user = userMapper.selectByPrimaryKey(id);
        //检验用户是否存在
        if (user==null){
            log.info(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        if (file.isEmpty()){
            log.info(ResultCode.FAILED_NOT_EXISTS.toString());
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_NOT_EXISTS));
        }
        String contentType = file.getContentType();
        if (!contentType.equals("image/jpeg") && !contentType.equals("image/png")) {
            log.info(ResultCode.FAILED_AVATAR_FORMAT.toString());
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_AVATAR_FORMAT));
        }
        if (file.getSize() > 2 * 1024 * 1024) {
            log.info(ResultCode.FAILED_AVATAR_OVER_SIZE.toString());
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_AVATAR_OVER_SIZE));
        }
        String originalFilename = file.getOriginalFilename();
        String fileExtension="";
        if (originalFilename!=null&&originalFilename.contains(".")){
            fileExtension=originalFilename.substring(originalFilename.lastIndexOf("."));
        }
        String timestamp = String.valueOf(System.currentTimeMillis());
        String filename="avatar_"+user.getId()+"_"+timestamp+fileExtension;

        // 确定文件存储路径
        File directory = new File(avatarDir);
        if (!directory.exists()) {
            directory.mkdirs(); // 创建目录如果不存在
        }

        // 保存文件
        String filePath = avatarDir + filename;
        File dest = new File(filePath);
        file.transferTo(dest);

        //删除原本的头像
        if (!StringUtil.isEmpty(user.getAvatarUrl())){
            String passFilePath = avatarDir+user.getAvatarUrl().replace("/","");
//            System.out.println(passFilePath);
            File oldFile = new File(passFilePath);
            if (oldFile.exists()) {
                oldFile.delete();
            }
        }

        String avatarUrl = "/" + filename; // 根据静态资源映射配置的路径
        user.setAvatarUrl(avatarUrl);
        user.setUpdateTime(new Date());
        userMapper.updateByPrimaryKey(user);
        return avatarUrl;
    }

    @Override
    public void addOneArticleCountById(Long id) {
        if (id==null||id<=0){
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        User user = userMapper.selectByPrimaryKey(id);
        if (user==null){
            log.info(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        User updateUser = new User();
        updateUser.setId(id);
        updateUser.setArticleCount(user.getArticleCount()+1);
        updateUser.setUpdateTime(new Date());
        int result = userMapper.updateByPrimaryKeySelective(updateUser);
        if (result<=0) {
            log.warn(ResultCode.FAILED.toString() + ", 受影响行数不等于1,");
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED));
        }
    }

    @Override
    public void subOneArticleCountById(Long id) {
        if (id==null||id<=0){
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        User user = userMapper.selectByPrimaryKey(id);
        if (user==null){
            log.info(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        User updateUser = new User();
        updateUser.setId(id);
        updateUser.setArticleCount(user.getArticleCount()-1);
        if (updateUser.getArticleCount()<0){
            updateUser.setArticleCount(0);
        }
        updateUser.setUpdateTime(new Date());
        int result = userMapper.updateByPrimaryKeySelective(updateUser);
        if (result<=0) {
            log.warn(ResultCode.FAILED.toString() + ", 受影响行数不等于1,");
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED));
        }
    }


}
